﻿//------------------------------------------------------------------------------
// <copyright file="Settings.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
// <summary>
// A class to handle specific events on the settings class.
// </summary>
//------------------------------------------------------------------------------

namespace Microsoft.Internal.GamesTest.Rpc.Tests.RemoteLoopback
{
    // Standard namespaces...
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Xml;
    using System.Xml.Serialization;

    // User-defined namespaces...
    using Microsoft.Internal.GamesTest.Rpc.Tests.Utilities;

    /// <summary>
    /// A class to handle specific events on the settings class.
    /// </summary>
    public class Settings
    {
        private static Settings instance = Load();

        /// <summary>
        /// Initializes a new instance of the <see cref="Settings" /> class.
        /// </summary>
        public Settings()
        {
            // Set defaults
            this.InboundPort = 4600;
            this.OutboundPort = 4600;
            this.CloseConnectionTimeout = 1 * Constants.MsPerSecond;
            this.DataBufferSize = 4096;
            this.PendingConnectionCheckInterval = 500;            
        }

        /// <summary>
        /// Gets the default settings instance.
        /// </summary>
        public static Settings Default
        {
            get
            {
                return instance;
            }
        }

        /// <summary>
        /// Gets or sets the inbound port number to create the listener on.
        /// </summary>
        /// <value>The inbound port number to create the listener on.</value>
        public int InboundPort { get; set; }

        /// <summary>
        /// Gets or sets the outbound port number to redirect the data to.
        /// </summary>
        /// <value>The outbound port number to redirect the data to.</value>
        public int OutboundPort { get; set; }

        /// <summary>
        /// Gets or sets the outbound target to redirect the data to.
        /// </summary>
        /// <value>The outbound target to redirect the data to.</value>
        public string OutboundTarget { get; set; }

        /// <summary>
        /// Gets or sets the number of milliseconds to wait for the connection to close before timing out.
        /// </summary>
        /// <value>The number of milliseconds to wait for the connection to close before timing out.</value>
        public int CloseConnectionTimeout { get; set; }

        /// <summary>
        /// Gets or sets the buffer size to use when reading data from clients.
        /// </summary>
        /// <value>The buffer size to use when reading data from clients.</value>
        public int DataBufferSize { get; set; }

        /// <summary>
        /// Gets or sets the number of milliseconds to wait between checks to see if pending connections are available.
        /// </summary>
        /// <value>The number of milliseconds to wait between checks to see if pending connections are available.</value>
        public int PendingConnectionCheckInterval { get; set; }

        /// <summary>
        /// Gets or sets the number of milliseconds to wait between checks to see if data is available to read.
        /// </summary>
        /// <value>The number of milliseconds to wait between checks to see if data is available to read.</value>
        public int PendingReadCheckInterval { get; set; }

        /// <summary>
        /// Loads settings from XML file in application directory.
        /// </summary>
        /// <returns>Loaded settings.</returns>
        private static Settings Load()
        {
            string path = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetExecutingAssembly().Location) + ".config");

            if (File.Exists(path))
            {
                using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
                {
                    // Read the file...
                    XmlReader reader = XmlReader.Create(stream);

                    // Create the serializer...
                    XmlSerializer serializer = new XmlSerializer(typeof(Settings), string.Empty);

                    // Read the file...
                    return (Settings)serializer.Deserialize(reader);
                }
            }
            else
            {
                // Use defaults
                return new Settings();
            }
        }
    }
}
